package com.xk._01基础篇._11哈希表;

import com.xk._01基础篇._11哈希表.file.FileInfo;
import com.xk._01基础篇._11哈希表.file.Files;
import com.xk._01基础篇._11哈希表.map.HashMap;
import com.xk._01基础篇._11哈希表.map.LinkedHashMap;
import com.xk._01基础篇._11哈希表.map.Map;
import com.xk._01基础篇._11哈希表.map.TreeMap;
import com.xk._01基础篇._11哈希表.model.Key;
import com.xk._01基础篇._11哈希表.model.Person;
import com.xk._01基础篇._11哈希表.model.SubKey1;
import com.xk._01基础篇._11哈希表.model.SubKey2;
import com.xk.tools.Asserts;
import com.xk.tools.Times;

/**
 * @description:
 * @author: xu
 * @date: 2022/9/27 11:09
 */
public class Main {
    public static void main(String[] args) {
        /*test2(new LinkedHashMap<>());
        test3(new LinkedHashMap<>());
        test4(new LinkedHashMap<>());
        test5(new LinkedHashMap<>());
        test1();*/

        float floatNum = 10.7f;
        // float数据对应的二进制数的整数
        int n = Float.floatToIntBits(floatNum);
        System.out.println(n); // 1093350195
        // float数据对应的二进制数
        String bn = Integer.toBinaryString(n);
        System.out.println(bn); // 1000001001010110011001100110011
        System.out.println(Float.hashCode(floatNum)); // 1093350195
    }

    static void test1() {
        String filepath1 = "X:\\newJava\\JDK8\\src";
        String filepath = "X:\\newJava\\JDK8\\src\\java\\util\\concurrent";
        FileInfo fileInfo = Files.read(filepath, null);
        String[] words = fileInfo.words();

        System.out.println("总行数：" + fileInfo.getLines());
        System.out.println("单词总数：" + words.length);
        System.out.println("-------------------------------------");

        test1Map(new TreeMap<>(), words);
        test1Map(new HashMap<>(), words);
        test1Map(new LinkedHashMap<>(), words);
    }

    static void test1Map(Map<String, Integer> map, String[] words) {
        Times.test(map.getClass().getSimpleName(), new Times.Task() {
            @Override
            public void execute() {
                for (String word : words) {
                    Integer count = map.get(word);
                    count = count == null ? 0 : count;
                    map.put(word, count + 1);
                }
                System.out.println(map.size());

                int count = 0;
                for (String word : words) {
                    Integer i = map.get(word);
                    count += i == null ? 0 : i;
                    map.remove(word);
                }
                Asserts.test(count == words.length);
                Asserts.test(map.size() == 0);
            }
        });
    }

    static void test2(HashMap<Object, Integer> map) {
        for (int i = 1; i <= 20; i++) {
            map.put(new Key(i), i);
        }
        for (int i = 5; i <= 7; i++) {
            map.put(new Key(i), i + 5);
        }
        Asserts.test(map.size() == 20);
        Asserts.test(map.get(new Key(4)) == 4);
        Asserts.test(map.get(new Key(5)) == 10);
        Asserts.test(map.get(new Key(6)) == 11);
        Asserts.test(map.get(new Key(7)) == 12);
        Asserts.test(map.get(new Key(8)) == 8);
    }

    static void test3(HashMap<Object, Integer> map) {
        map.put(null, 1); // 1
        map.put(new Object(), 2); // 2
        map.put("jack", 3); // 3
        map.put(10, 4); // 4
        map.put(new Object(), 5); // 5
        map.put("jack", 6);
        map.put(10, 7);
        map.put(null, 8);
        map.put(10, null);
        Asserts.test(map.size() == 5);
        Asserts.test(map.get(null) == 8);
        Asserts.test(map.get("jack") == 6);
        Asserts.test(map.get(10) == null);
        Asserts.test(map.get(new Object()) == null);
        Asserts.test(map.containsKey(10));
        Asserts.test(map.containsKey(null));
        Asserts.test(map.containsValue(null));
        Asserts.test(map.containsValue(1) == false);
    }

    static void test4(HashMap<Object, Integer> map) {
        map.put("jack", 1);
        map.put("rose", 2);
        map.put("jim", 3);
        map.put("jake", 4);
        map.remove("jack");
        map.remove("jim");
        for (int i = 1; i <= 10; i++) {
            map.put("test" + i, i);
            map.put(new Key(i), i);
        }
        for (int i = 5; i <= 7; i++) {
            Asserts.test(map.remove(new Key(i)) == i);
        }
        for (int i = 1; i <= 3; i++) {
            map.put(new Key(i), i + 5);
        }
        Asserts.test(map.size() == 19);
        Asserts.test(map.get(new Key(1)) == 6);
        Asserts.test(map.get(new Key(2)) == 7);
        Asserts.test(map.get(new Key(3)) == 8);
        Asserts.test(map.get(new Key(4)) == 4);
        Asserts.test(map.get(new Key(5)) == null);
        Asserts.test(map.get(new Key(6)) == null);
        Asserts.test(map.get(new Key(7)) == null);
        Asserts.test(map.get(new Key(8)) == 8);
        map.traversal(new Map.Visitor<Object, Integer>() {
            public boolean visit(Object key, Integer value) {
                System.out.println(key + "_" + value);
                return false;
            }
        });
    }

    static void test5(HashMap<Object, Integer> map) {
        for (int i = 1; i <= 20; i++) {
            map.put(new SubKey1(i), i);
        }
        map.put(new SubKey2(1), 5);
        Asserts.test(map.get(new SubKey1(1)) == 5);
        Asserts.test(map.get(new SubKey2(1)) == 5);
        Asserts.test(map.size() == 20);
        map.print();
    }

    private static void test02(){
        SubKey1 key1 = new SubKey1(1);
        SubKey2 key2 = new SubKey2(1);

        HashMap<Object, Integer> map = new HashMap<>();
        map.put(key1, 1);
        map.put(key2, 2);

        System.out.println(key1.equals(key2));// true
        System.out.println("map.size() = " + map.size());

        System.out.println("map.get(key1) = " + map.get(key1));
        System.out.println("map.get(key2) = " + map.get(key2));
    }

    private static void test01(){
        Person p1 = new Person("jack", 20, 1.88f);
        Person p2 = new Person("rose", 18, 1.66f);

        System.out.println(p1.equals(p2));
        System.out.println(p1.compareTo(p2));
    }

    private static void testHashMap1(){
        HashMap<Object, Integer> map = new HashMap<>();
        for (int i = 1; i <= 18; i++) {
            map.put(new Key(i), i);
        }
        map.print();
        System.out.println(map.size());

        map.put(new Key(19), 100);
        map.traversal(new Map.Visitor<Object, Integer>() {
            @Override
            public boolean visit(Object key, Integer value) {
                System.out.println(key + "_" + value);
                return false;
            }
        });

        System.out.println("=====================");
        System.out.println(map.get(new Key(1)));
        System.out.println(map.get(new Key(2)));
        System.out.println(map.get(new Key(3)));
        System.out.println(map.get(new Key(4)));
        System.out.println(map.get(new Key(5)));
        System.out.println(map.get(new Key(6)));
        System.out.println(map.get(new Key(7)));

        System.out.println("==============");
    }

    private static void testPerson(){
        Person p1 = new Person("jack", 15, 1.69f);
        Person p2 = new Person("jack", 15, 1.69f);
        System.out.println("p1.hashCode() = " + p1.hashCode());
        System.out.println("p2.hashCode() = " + p2.hashCode());
        System.out.println("========================================================");

        Map<Object,Integer> map = new HashMap<>();
        map.put(p1, 1);
        map.put(p2, 3);
        map.put("jack", 1);
        map.put("rose", 1);
        map.put("jack", 5);
        map.put(null, 9);

        System.out.println(map.containsKey(p1));
        System.out.println(map.containsKey(null));
        System.out.println(map.containsValue(6));
        System.out.println(map.containsValue(1));
        System.out.println(map.containsKey("jack"));

        System.out.println(map.get("jack"));
        System.out.println(map.get("rose"));
        System.out.println(map.get(null));
        System.out.println(map.get(p1));
        System.out.println("===========================");

        map.traversal(new Map.Visitor<Object, Integer>() {
            @Override
            public boolean visit(Object key, Integer value) {
                System.out.println(key + "===" + value);
                return false;
            }
        });

        System.out.println("=======================");

        System.out.println("map.size() = " + map.size());
        System.out.println(map.remove("jack"));
        System.out.println("map.size() = " + map.size());
        System.out.println(map.remove("rose"));
        System.out.println("map.size() = " + map.size());
        System.out.println(map.remove(null));
        System.out.println("map.size() = " + map.size());
        System.out.println(map.remove(p1));
        System.out.println("map.size() = " + map.size());
    }

    private static void testNumHash(){
        int i = 110;
        float f = 10.6F;
        long l = 1324988888L;
        double d = 111111.011111;
        String str = "hashCode";

        System.out.println(Integer.hashCode(i));
        System.out.println(Float.hashCode(f));
        System.out.println(Long.hashCode(l));
        System.out.println(Double.hashCode(d));
        System.out.println(str.hashCode());
    }

    private static void testStringHash(){
        String string = "jack";
        int len = string.length();
        int hashCode = 0;
        for (int i = 0; i < len; i++) {
            char c = string.charAt(i);
            hashCode = hashCode * 31 + c;
        }
        // hashCode = (((0 * 31 + j) * 31 + a) * 31 + c) * 31 + k
        // hashCode = ((j * 31 + a) * 31 + c) * 31 + k
        // hashCode = (j * 31^2 + a * 31 + c) * 31 + k
        // hashCode = j * 31^3 + a * 31^2 + c * 31^1 + k * 31^0

        System.out.println(hashCode);
        System.out.println(string.hashCode());
    }
}
